<template>
    <div ref="movableSuper"
         class="movable-finder"
         :class="customClass + (penetrate?' pointer-event-none ': ' pointer-event-auto ')"
         :style="customStyle">
        <div ref="movableBox"
             class="movable-inner pointer-event-auto"
             @touchstart="onTouchstart('movableBox', $event)"
             @touchmove="onTouchmove('movableBox', $event)">
            <slot/>
        </div>
    </div>
</template>

<script type="es6">
	export default {
		name: "ok-movable",
		props: {
			"position": { //    方向
				type: String,
				default: "",
			},
			"x": { // 内部移动元素的x位置
				type: [Number, String],
				default: 0
			},
			"y": { // 内部移动元素的y位置
				type: [Number, String],
				default: 0
			},
			"penetrate": { //   是否穿透外部元素(使滑动区域不覆盖外部元素)
				type: Boolean,
				default: true
			},
			'customStyle': {
				type: String,
				default: ''
			},
			'customClass': {
				type: String,
				default: ''
			},
		},
		watch: {
			"position": function (val) {
				this.onPosition();
			},
			"x": function (val) {
				this.onLocation()
			},
			"y": function (val) {
				this.onLocation()
			}
		},
		data() {
			return {
				coordinate: {
					client: {},
					elePosition: {}
				}
			}
		},
		mounted() {
			let position = this.position;
			if (position) {
				this.onPosition();
			} else {
				this.onLocation();
			}
		},
		methods: {
			/**位置*/
			onLocation() {
				// 限制可移动距离，不超出可视区域
				let x = this.x;
				let y = this.y;
				let movableSuper = this.$refs.movableSuper,
					movableBox = this.$refs.movableBox,
					offsetWidth = movableSuper.offsetWidth,     //可视区域的宽度
					offsetHeight = movableSuper.offsetHeight;   //可视区域的高度
				if (!isNaN(x * 1)) {
					x = x <= 0 ? 0 : x >= offsetWidth - movableBox.offsetWidth ? offsetWidth - movableBox.clientWidth : x;
					x += "px";
				}
				if (!isNaN(y * 1)) {
					y = y <= 0 ? 0 : y >= offsetHeight - movableBox.offsetHeight ? offsetHeight - movableBox.offsetHeight : y;
					y += "px";
				}
				movableBox.style.left = x;
				movableBox.style.top = y;
			},

			/**方向*/
			onPosition() {
				let position = this.position;
				/**top,left,right,bottom,center*/
				let x = 0,
					y = 0,
					movableSuper = this.$refs.movableSuper,
					movableBox = this.$refs.movableBox,
					offsetWidth = movableSuper.offsetWidth,     //可视区域的宽度
					offsetHeight = movableSuper.offsetHeight,   //可视区域的高度
					elemWidth = movableBox.offsetHeight,//元素宽度
					elemHeight = movableBox.offsetHeight;//元素高度

				let center = offsetWidth / 2 - elemWidth / 2;
				let middle = offsetHeight / 2 - elemHeight / 2;
				let right = offsetWidth - elemWidth;
				let bottom = offsetHeight - elemHeight;
				//left center right top middle bottom
				switch (position) {
					case "center": //中部居中
						x = center;
						y = middle;
						break;
					case "lt":  //左上
						x = 0;
						y = 0;
						break;
					case "ct":  //中上
						x = center;
						y = 0;
						break;
					case "rt":  //右上
						x = right;
						y = 0;
						break;
					case "lm":  //左中
						x = 0;
						y = middle;
						break;
					case "cm":  //中部居中
						x = center;
						y = middle;
						break;
					case "rm":  //右中
						x = right;
						y = middle;
						break;
					case "lb":  //左下
						x = 0;
						y = bottom;
						break;
					case "cb":  //中下
						x = center;
						y = bottom;
						break;
					case "rb":  //右下
						x = right;
						y = bottom;
						break;
				}
				movableBox.style.left = x + "px";
				movableBox.style.top = y + "px";
			},

			onTouchstart(refName, e) {
				// e.preventDefault();
				let element = e.targetTouches[0];
				// 记录点击的坐标
				this.coordinate.client = {
					x: element.clientX,
					y: element.clientY
				};
				// 记录需要移动的元素坐标
				this.coordinate.elePosition.left = this.$refs[refName].offsetLeft;
				this.coordinate.elePosition.top = this.$refs[refName].offsetTop;
			},

			onTouchmove(refName, e) {
				e.preventDefault();
				let movableSuper = this.$refs.movableSuper,
					offsetWidth = movableSuper.offsetWidth,     //可视区域的宽度
					offsetHeight = movableSuper.offsetHeight;   //可视区域的高度
				let element = e.targetTouches[0];

				// 根据初始 client 位置计算移动距离(元素移动位置=元素初始位置+光标移动后的位置-光标点击时的初始位置)
				let x = this.coordinate.elePosition.left + (element.clientX - this.coordinate.client.x);
				let y = this.coordinate.elePosition.top + (element.clientY - this.coordinate.client.y);

				// 限制可移动距离，不超出可视区域
				x = x <= 0 ? 0 : x >= offsetWidth - this.$refs[refName].offsetWidth ? offsetWidth - this.$refs[refName].offsetWidth : x;
				y = y <= 0 ? 0 : y >= offsetHeight - this.$refs[refName].offsetHeight ? offsetHeight - this.$refs[refName].offsetHeight : y;

				// 移动当前元素
				this.$refs[refName].style.left = x + 'px';
				this.$refs[refName].style.top = y + 'px';
				this.$refs[refName].style.right = 'auto';
				this.$refs[refName].style.bottom = 'auto';
			}
		}
	}
</script>

<style lang="scss" scoped>
    .movable-finder{
        position: relative;
        width: 100%;
        height: 100px;
        background: #f5f5f5;
        overflow: hidden;
    }

    .movable-inner {
        z-index: 9;
        bottom: auto;
        right: auto;
        position: absolute;
    }

    /**鼠标事件触发*/

    .pointer-event-none {
        pointer-events: none !important;
    }
    .pointer-event-auto { /*默认*/
        pointer-events: auto !important;
    }
</style>